package gov.nasa.anml.lifted;

import java.util.HashMap;

import gov.nasa.anml.PDDL;
import gov.nasa.anml.State;
import gov.nasa.anml.PDDL.FloatExpression;
import gov.nasa.anml.utility.*;

public class ANMLFloat extends SimpleFloat implements ConstantExpression<SimpleFloat> {

	public static final fHashMap<ANMLFloat> pool = new fHashMap<ANMLFloat>();
	
	// warning: testing for NaN cannot be done by == Float.NaN
	// however, testing ANMLFloats for == ANMLFloat.NaN does work
	// because of the extra check in make() 
	//public static final ANMLFloat NaN = new ANMLFloat(Float.NaN); 
	// just use null for NaN, because other types don't have an internal
	// 'undefined'
	public static final ANMLFloat PInf = make(Float.POSITIVE_INFINITY);
	public static final ANMLFloat NInf = make(Float.NEGATIVE_INFINITY);
	public static final ANMLFloat ZeroF = make(0f);
	public static final ANMLFloat OneF = make(1f);
	// epsilon, non-final, with initial value at 0.01? or too pddl specific?
	// "unit" instead of "epsilon" is maybe better, but still kludgy...
	
	public static ANMLFloat make(float v) {
		ANMLFloat probe = pool.get(v);
		if (probe == null) {
			if (v != v)
				return null;
			probe = new ANMLFloat(v);
			pool.put(v,probe);
		}
		return probe;
	}

	protected ANMLFloat(float v) {
		super(v);
	}
	
	public ANMLFloat value(State s) {
		return this;
	}

	public ANMLFloat value() {
		return this;
	}

	public TypeCode typeCode() {
		return TypeCode.Float;
	}

	public History<SimpleVoid> storage(State p, State c) {
		return null;
	}

	public boolean apply(State p, int contextID, State c) {
		return false;
	}

	public transient PDDL.FloatLiteral asPDDLFloatExpression;
	
	public FloatExpression asPDDLFloatExpr() {
		return asPDDLFloatExpression;
	}

	public void translateDecl(PDDL pddl, Interval unit) {
	}	
	public PDDL.FloatExpression translateExpr(PDDL pddl, Interval unit) {
		return asPDDLFloatExpression = pddl.new FloatLiteral(v);
	}
	public PDDL.Expression translateLValue(PDDL pddl, Interval unit) {
		return null;
	}
	
	public PDDL.Argument translateArgument(PDDL pddl, Interval unit) {
		return null;
	}

	public void translateStmt(PDDL pddl, Interval unit, PDDL.Time part) {
		unit.getPDDLConditions().add(pddl.FalseCondition);
	}
	

}